home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
CBGRX103.ZIP
/
contrib
/
libgrx
/
src
/
pibitblt.c
< prev
next >
Wrap
Text File
|
1993-12-06
|
6KB
|
208 lines
/**
** PIBITBLT.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**/
#include "p8514a.h"
#include "memcopy.h"
static int blitmixes[] = {
MIX_REPLACE | FSS_BITBLT,
MIX_XOR | FSS_BITBLT,
MIX_OR | FSS_BITBLT,
MIX_AND | FSS_BITBLT
};
static int pc_blitmixes[] = {
MIX_REPLACE | FSS_PCDATA,
MIX_XOR | FSS_PCDATA,
MIX_OR | FSS_PCDATA,
MIX_AND | FSS_PCDATA
};
void _GrPIPixCopy(GC *dst,long daddr,GC *src,long saddr,int w,int h,int op)
{
pixptr dstp,srcp;
int doff,soff;
int oper = C_OPER(op);
if((w <= 0) || (h <= 0)) return;
_ClrDir();
if(dst->gc_onscreen) {
if(src->gc_onscreen) {
WaitQueue(8);
outpw(MAJ_AXIS_PCNT,(w - 1));
outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
outpw(FRGD_MIX,blitmixes[oper]);
if(daddr > saddr) {
outpw(CUR_X,COORD_X(saddr) + w - 1);
outpw(CUR_Y,COORD_Y(saddr) + h - 1);
outpw(DESTX_DIASTP,COORD_X(daddr) + w - 1);
outpw(DESTY_AXSTP,COORD_Y(daddr) + h - 1);
outpw(CMD,(CMD_BITBLT | DRAW | PLANAR | WRTDATA));
}
else {
outpw(CUR_X,COORD_X(saddr));
outpw(CUR_Y,COORD_Y(saddr));
outpw(DESTX_DIASTP,COORD_X(daddr));
outpw(DESTY_AXSTP,COORD_Y(daddr));
outpw(CMD,(CMD_BITBLT | INC_X | INC_Y | DRAW | PLANAR | WRTDATA));
}
return;
}
WaitQueue(6);
outpw(CUR_X,COORD_X(daddr));
outpw(CUR_Y,COORD_Y(daddr));
outpw(MAJ_AXIS_PCNT,(w - 1));
outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
outpw(FRGD_MIX,pc_blitmixes[oper]);
srcp = P_ADDRESS(src,saddr);
soff = src->gc_lineoffset - w;
#ifdef __TURBOC__
#define _HAVE_INLINE_
if((w | soff | (int)srcp) & 1) {
outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
WaitQueue(8);
asm cld;
asm push ds;
asm lds si,srcp;
asm mov bx,WORD PTR h;
asm mov dx,PIX_TRANS;
BVLoop:
asm mov cx,WORD PTR w;
BHLoop:
asm lodsb;
asm out dx,ax;
asm loop BHLoop;
asm add si,WORD PTR soff;
asm dec bx;
asm jne BVLoop;
asm pop ds;
}
else {
w >>= 1;
outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | _16BIT | BYTSEQ | DRAW | WRTDATA));
WaitQueue(8);
asm .286
asm cld;
asm push ds;
asm lds si,srcp;
asm mov bx,WORD PTR h;
asm mov dx,PIX_TRANS;
WLoop:
asm mov cx,WORD PTR w;
asm rep outsw;
asm add si,WORD PTR soff;
asm dec bx;
asm jne WLoop;
asm pop ds;
}
#endif
#ifdef __GNUC__
#define _HAVE_INLINE_
if((w | soff | (int)srcp) & 1) {
outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
WaitQueue(8);
asm volatile(" \n\
cld \n\
movl %0,%%esi \n\
movl %1,%%ebx \n\
movl %2,%%edx \n\
L_BVLoop: \n\
movl %3,%%ecx \n\
L_BHLoop: \n\
lodsb \n\
outw %%ax,%%dx \n\
loop L_BHLoop \n\
addl %4,%%esi \n\
decl %%ebx \n\
jne L_BVLoop "
: /* no inputs */
: "g" (srcp), "g" (h), "g" (PIX_TRANS), "g" (w), "g" (soff)
: "si", "dx", "cx", "bx", "ax"
);
}
else {
w >>= 1;
outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | _16BIT | BYTSEQ | DRAW | WRTDATA));
WaitQueue(8);
asm volatile(" \n\
cld \n\
movl %0,%%esi \n\
movl %1,%%ebx \n\
movl %2,%%edx \n\
L_WLoop: \n\
movl %3,%%ecx \n\
rep \n\
outsw \n\
addl %4,%%esi \n\
decl %%ebx \n\
jne L_WLoop "
: /* no inputs */
: "g" (srcp), "g" (h), "g" (PIX_TRANS), "g" (w), "g" (soff)
: "si", "dx", "cx", "bx"
);
}
#endif
#ifndef _HAVE_INLINE_
outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
WaitQueue(8);
while(--h >= 0) {
for(doff = w; --doff >= 0; ) outpw(PIX_TRANS,*srcp++);
srcp += soff;
}
#endif
return;
}
if(src->gc_onscreen) {
int command = CMD_RECT | INC_X | INC_Y | PCDATA | DRAW;
WaitQueue(6);
outpw(CUR_X,COORD_X(saddr));
outpw(CUR_Y,COORD_Y(saddr));
outpw(MAJ_AXIS_PCNT,(w - 1));
outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
outpw(CMD,command);
dstp = P_ADDRESS(dst,daddr);
doff = dst->gc_lineoffset - w;
while((inpw(GP_STAT) & DATARDY) == 0);
while(--h >= 0) {
switch(oper) {
case C_XOR:
for(soff = w; --soff >= 0; *dstp++ ^= inpw(PIX_TRANS));
break;
case C_OR:
for(soff = w; --soff >= 0; *dstp++ |= inpw(PIX_TRANS));
break;
case C_AND:
for(soff = w; --soff >= 0; *dstp++ &= inpw(PIX_TRANS));
break;
default:
for(soff = w; --soff >= 0; *dstp++ = inpw(PIX_TRANS));
break;
}
dstp += doff;
}
return;
}
_GrP8PixCopy(dst,daddr,src,saddr,w,h,op);
}